package model

import (
	"errors"
	"github.com/jinzhu/gorm"
)

// JobInfo represents a video info
type JobInfo struct {
	gorm.Model
	Name             string `json:"name"`
	Type             int64  `json:"type"`
	AlgorithmID      int64  `json:"algorithm_id"`
	BeginTime        string `json:"begin_time"`
	EndTime          string `json:"end_time"`
	Progress         int64  `json:"progress"`
	DataType         int64  `json:"data_type"`
	VideoID          int64  `json:"video_id"`
	DatasetID        int64  `json:"dataset_id"`
	ResultPath       string `json:"result_path"`
	ResultStatistics string `json:"result_statistics"`
	CreatedTime      string `json:"created_time"`
	FinishedTime     string `json:"finished_time"`
	Status           int64  `json:"status"`
	ErrorCode        int64  `json:"error_code"`
	ErrorMsg         string `json:"error_msg"`
	UserID           int64  `json:"user_id"`
	SearchImagePath  string `json:"search_image_path"`
}

// AddNewJob add a new Job
func AddNewJob(jobInfo *JobInfo) interface{} {
	job := db.Save(jobInfo)
	return job.Value
}

// ExistJobByName check the video name is exist or not
func ExistJobByName(name string) bool {
	var video JobInfo
	db.Select("id").Where("name = ?", name).First(&video)
	if video.ID > 0 {
		return true
	}
	return false
}

// GetJob get a single Job
func GetJob(JobID string) (*JobInfo, error) {
	var Job JobInfo
	// SELECT * FROM Job WHERE id = JobID;
	db.First(&Job, JobID)
	if Job.ID == 0 {
		err := errors.New("no Job found")
		return &JobInfo{}, err
	}
	return &Job, nil
}

// GetJobWithVideoOrAlgorithm get a job by video id or algorithm id
func GetJobWithVideoOrAlgorithm(videoID string, algorithmID string) ([]JobInfo, error) {
	var job []JobInfo

	if videoID == "" {
		db.Where("algorithm_id = ?", algorithmID).Find(&job)
	} else if algorithmID == "" {
		db.Where("video_id = ?", videoID).Find(&job)
	} else {
		db.Where("algorithm_id = ? AND video_id = ?", algorithmID, videoID).Find(&job)
	}

	if len(job) == 0 {
		err := errors.New("no job found")
		return []JobInfo{}, err
	}

	return job, nil
}

// GetJobWithVideoOrAlgorithm get a job by video id or algorithm id
func GetJobWithDatasetOrAlgorithm(dataSetID string, algorithmID string) ([]JobInfo, error) {
	var job []JobInfo

	if dataSetID == "" {
		db.Where("algorithm_id = ?", algorithmID).Find(&job)
	} else if algorithmID == "" {
		db.Where("dataset_id = ?", dataSetID).Find(&job)
	} else {
		db.Where("algorithm_id = ? AND dataset_id = ?", algorithmID, dataSetID).Find(&job)
	}

	if len(job) == 0 {
		err := errors.New("no job found")
		return []JobInfo{}, err
	}

	return job, nil
}

// GetJobByUserID get job info from db by user id
func GetJobByUserID(ID string) ([]JobInfo, error) {
	var myJobs []JobInfo
	db.Where("user_id = ?", ID).Find(&myJobs)
	if len(myJobs) == 0 {
		err := errors.New("no job found")
		return []JobInfo{}, err
	}
	return myJobs, nil
}

// ExistJob check the video name is exist or not
func ExistJob(algorithmID, videoID, datasetID int64) (bool, JobInfo) {
	var job JobInfo
	if videoID != 0 {
		db.Where("algorithm_id = ? AND video_id = ?", algorithmID, videoID).Find(&job)
	} else {
		db.Where("algorithm_id = ? AND dataset_id = ?", algorithmID, datasetID).Find(&job)
	}

	if job.ID > 0 {
		return true, job
	}
	return false, JobInfo{}
}

// ExistJobByID check the id is exist or not
func ExistJobByID(ID int) bool {
	var myJob JobInfo
	db.Select("id").Where("id = ?", ID).First(&myJob)
	if myJob.ID > 0 {
		return true
	}
	return false
}

// UpdateJob edit user info
func UpdateJob(id int, data interface{}) bool {
	db.Model(&JobInfo{}).Where("id = ?", id).Updates(data)

	return true
}

// DeleteJob delete the user info from db
func DeleteJob(id int) bool {
	db.Where("id = ?", id).Delete(&JobInfo{})

	return true
}

// GetAllJobs get the all Jobs info from db
func GetAllJobs() (result []JobInfo, err error) {
	var myJob []JobInfo
	db.Find(&myJob)

	if len(myJob) == 0 {
		return nil, err
	}
	return myJob, nil
}
